package cn.nexttec.lib_rich_editor

import android.app.Activity
import android.content.Context
import android.graphics.BitmapFactory
import android.graphics.Color
import android.graphics.Typeface
import android.graphics.drawable.BitmapDrawable
import android.net.Uri
import android.text.Editable
import android.text.Spannable
import android.text.SpannableString
import android.text.SpannableStringBuilder
import android.text.TextWatcher
import android.text.style.*
import android.util.AttributeSet
import android.util.TypedValue
import android.view.Gravity
import android.view.LayoutInflater
import android.widget.*
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.DrawableRes
import androidx.appcompat.app.AppCompatActivity

sealed class EditorButton {
    data class TextButton(val label: String, val handler: () -> Unit) : EditorButton()
    data class ImageButton(@DrawableRes val resId: Int, val handler: () -> Unit) : EditorButton()
}

interface NoteListener {
    fun onNoteChanged(isEmpty:Boolean)

}

class RichEditorView @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null
) : LinearLayout(context, attrs), MarkdownContract {

    private var callback:NoteListener? = null
    private var imagePickerLauncher: ActivityResultLauncher<String>? = null
    private val colorSelector: LinearLayout
    private val circleDiameter = 20.dpToPx()
    private val touchAreaSize = 40.dpToPx()
    private val editor: EditText
    private val toolbarRow1: LinearLayout
    private val toolbarRow2: LinearLayout
    private val btnSize = 48.dpToPx()

    private var currentTextColor: Int = Color.BLACK

    private val colors = listOf(
        Color.parseColor("#F44336"), Color.parseColor("#FF9800"), Color.parseColor("#FFEB3B"),
        Color.parseColor("#4CAF50"), Color.parseColor("#2196F3"), Color.parseColor("#9C27B0"),
        Color.parseColor("#000000")
    )

    init {
        orientation = VERTICAL
        LayoutInflater.from(context).inflate(R.layout.view_rich_editor, this, true)
        editor = findViewById(R.id.editorArea)
        toolbarRow1 = findViewById(R.id.toolbarRow1)
        toolbarRow2 = findViewById(R.id.toolbarRow2)
        colorSelector = findViewById(R.id.colorSelector)

        setupToolbar()
        setupColorSelector()
        setupTextWatcher()
    }

    fun addListener(listener: NoteListener){
        this.callback = listener
    }

    private fun setupTextWatcher() {
        var beforeChangeStart = 0
        var beforeChangeText: CharSequence? = null

        editor.addTextChangedListener(object : TextWatcher {
            override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
                beforeChangeStart = start
                beforeChangeText = s?.subSequence(start, start + count)
            }

            override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
            override fun afterTextChanged(s: Editable?) {
                callback?.onNoteChanged(s.isNullOrEmpty())
                s ?: return
                val insertedLength = s.length - (beforeChangeText?.length ?: 0)
                if (insertedLength <= 0) return

                val start = beforeChangeStart
                val end = start + insertedLength
                if (start < 0 || end > s.length || end <= start) return

                // 给新输入文字加当前颜色span
                s.setSpan(
                    ForegroundColorSpan(currentTextColor),
                    start,
                    end,
                    Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
                )
            }
        })
    }

    private fun setupToolbar() {
        val buttonsRow1 = listOf(
            EditorButton.ImageButton(R.drawable.baseline_format_bold_24, ::onBoldClicked),
            EditorButton.ImageButton(R.drawable.baseline_format_italic_24, ::onItalicClicked),
            EditorButton.ImageButton(
                R.drawable.baseline_format_underlined_24,
                ::onUnderlineClicked
            ),
            EditorButton.ImageButton(
                R.drawable.baseline_strikethrough_s_24,
                ::onStrikethroughClicked
            ),
            EditorButton.TextButton("H1", ::onHeading1Clicked),
            EditorButton.TextButton("H2", ::onHeading2Clicked),
            EditorButton.TextButton("H3", ::onHeading3Clicked)
        )
        val buttonsRow2 = listOf(
            EditorButton.ImageButton(
                R.drawable.baseline_format_list_numbered_24,
                ::onOrderedListClicked
            ),
            EditorButton.ImageButton(
                R.drawable.baseline_format_list_bulleted,
                ::onUnorderedListClicked
            ),
            EditorButton.ImageButton(R.drawable.baseline_code_24, ::onCodeBlockClicked),
            EditorButton.ImageButton(
                R.drawable.baseline_format_indent_increase_24,
                ::onFormatIndentIncreaseClicked
            ),
            EditorButton.ImageButton(
                R.drawable.baseline_format_indent_decrease_24,
                ::onFormatIndentDecreaseClicked
            ),
            EditorButton.ImageButton(R.drawable.eraser, ::onClearStyleClicked),
            EditorButton.ImageButton(R.drawable.baseline_image_24, ::onImageClicked)
        )
        buttonsRow1.forEach { addButtonToToolbar(it, toolbarRow1) }
        buttonsRow2.forEach { addButtonToToolbar(it, toolbarRow2) }
    }

    private fun addButtonToToolbar(button: EditorButton, toolbar: LinearLayout) {
        val attrs = intArrayOf(android.R.attr.selectableItemBackgroundBorderless)
        val typedArray = context.obtainStyledAttributes(attrs)
        val selectableBackground = typedArray.getDrawable(0)
        typedArray.recycle()

        val view = when (button) {
            is EditorButton.TextButton -> TextView(context).apply {
                text = button.label
                setTextSize(TypedValue.COMPLEX_UNIT_SP, 16f)
                setTextColor(Color.parseColor("#333333"))
                gravity = Gravity.CENTER
                background = selectableBackground
                isClickable = true
                isFocusable = true
                setOnClickListener { button.handler() }
            }

            is EditorButton.ImageButton -> ImageView(context).apply {
                setImageResource(button.resId)
                scaleType = ImageView.ScaleType.CENTER_INSIDE
                background = selectableBackground
                isClickable = true
                isFocusable = true
                setOnClickListener { button.handler() }
                setPadding(8.dpToPx(), 8.dpToPx(), 8.dpToPx(), 8.dpToPx())
            }
        }
        view.layoutParams =
            LinearLayout.LayoutParams(btnSize, btnSize).apply { marginEnd = 8.dpToPx() }
        toolbar.addView(view)
    }

    private fun setupColorSelector() {
        colors.forEach { colorInt ->
            val container = FrameLayout(context).apply {
                layoutParams = LinearLayout.LayoutParams(0, touchAreaSize, 1f)
                isClickable = true
                isFocusable = true
            }
            val colorCircle = ImageView(context).apply {
                layoutParams = FrameLayout.LayoutParams(circleDiameter, circleDiameter)
                    .apply { gravity = Gravity.CENTER }
                background = createCircleDrawable(colorInt)
                isClickable = false
            }
            container.addView(colorCircle)
            container.setOnClickListener { onColorSelected(colorInt) }
            colorSelector.addView(container)
        }
    }

    private fun createCircleDrawable(color: Int) =
        android.graphics.drawable.GradientDrawable().apply {
            shape = android.graphics.drawable.GradientDrawable.OVAL
            setColor(color)
            setStroke(2.dpToPx(), Color.DKGRAY)
        }

    private fun onColorSelected(colorInt: Int) {
        currentTextColor = colorInt
        applyColorToSelectionOrFutureInput()
    }

    private fun applyColorToSelectionOrFutureInput() {
        val start = editor.selectionStart
        val end = editor.selectionEnd
        if (start < 0 || end < 0) return
        val editable = editor.text
        if (start != end) {
            // 清除原有颜色样式，添加新颜色
            editable.getSpans(start, end, ForegroundColorSpan::class.java)
                .forEach { editable.removeSpan(it) }
            editable.setSpan(
                ForegroundColorSpan(currentTextColor),
                start,
                end,
                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
            )
        } else {
            editor.setTextColor(currentTextColor)
        }
    }

    // 清除span时去掉 NumberSpan
    private fun clearLineStyles(lineStart: Int, lineEnd: Int) {
        val editable = editor.text
        val spanTypes = arrayOf(
            StyleSpan::class.java,
            ForegroundColorSpan::class.java,
            UnderlineSpan::class.java,
            StrikethroughSpan::class.java,
            BulletSpan::class.java,
            BackgroundColorSpan::class.java,
            TypefaceSpan::class.java
        )
        spanTypes.forEach { type ->
            editable.getSpans(lineStart, lineEnd, type).forEach { editable.removeSpan(it) }
        }
    }

    // ---------- 样式应用入口（确保单一样式原则）

    private fun applyLineStyle(newStyle: LineStyleType) {
        clearCurrentLineStyle()
        val sel = editor.selectionStart
        if (sel < 0) return
        val text = editor.text
        val lineStart = text.lastIndexOf('\n', sel - 1).let { if (it == -1) 0 else it + 1 }
        val lineEnd = text.indexOf('\n', sel).let { if (it == -1) text.length else it }

        // 清除之前所有样式
        clearLineStyles(lineStart, lineEnd)

        when (newStyle) {
            LineStyleType.BOLD -> text.setSpan(
                StyleSpan(Typeface.BOLD),
                lineStart,
                lineEnd,
                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
            )

            LineStyleType.ITALIC -> text.setSpan(
                StyleSpan(Typeface.ITALIC),
                lineStart,
                lineEnd,
                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
            )

            LineStyleType.UNDERLINE -> text.setSpan(
                UnderlineSpan(),
                lineStart,
                lineEnd,
                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
            )

            LineStyleType.STRIKETHROUGH -> text.setSpan(
                StrikethroughSpan(),
                lineStart,
                lineEnd,
                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
            )

            LineStyleType.COLOR -> text.setSpan(
                ForegroundColorSpan(currentTextColor),
                lineStart,
                lineEnd,
                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
            )

            LineStyleType.HEADING1 -> {
                text.setSpan(
                    StyleSpan(Typeface.BOLD),
                    lineStart,
                    lineEnd,
                    Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
                )
                // 文字大小用绝对大小Span，这里使用 24sp
                text.setSpan(
                    AbsoluteSizeSpan(24, true),
                    lineStart,
                    lineEnd,
                    Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
                )
            }

            LineStyleType.HEADING2 -> {
                text.setSpan(
                    StyleSpan(Typeface.BOLD),
                    lineStart,
                    lineEnd,
                    Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
                )
                text.setSpan(
                    AbsoluteSizeSpan(20, true),
                    lineStart,
                    lineEnd,
                    Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
                )
            }

            LineStyleType.HEADING3 -> {
                text.setSpan(
                    StyleSpan(Typeface.BOLD),
                    lineStart,
                    lineEnd,
                    Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
                )
                text.setSpan(
                    AbsoluteSizeSpan(16, true),
                    lineStart,
                    lineEnd,
                    Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
                )
            }

            LineStyleType.ORDERED_LIST -> applyOrderedList(lineStart, lineEnd)
            LineStyleType.UNORDERED_LIST -> applyUnorderedList(lineStart, lineEnd)
            LineStyleType.CODE_BLOCK -> applyCodeBlock(lineStart, lineEnd)
            LineStyleType.NONE -> {}
        }
    }

    // ---------- 单样式类型枚举
    private enum class LineStyleType {
        NONE, COLOR, BOLD, ITALIC, UNDERLINE, STRIKETHROUGH,
        HEADING1, HEADING2, HEADING3,
        ORDERED_LIST, UNORDERED_LIST,
        CODE_BLOCK
    }

    // ---------- 具体样式处理实现

    private fun onBoldClicked() = applyLineStyle(LineStyleType.BOLD)
    private fun onItalicClicked() = applyLineStyle(LineStyleType.ITALIC)
    private fun onUnderlineClicked() = applyLineStyle(LineStyleType.UNDERLINE)
    private fun onStrikethroughClicked() = applyLineStyle(LineStyleType.STRIKETHROUGH)
    private fun onHeading1Clicked() = applyLineStyle(LineStyleType.HEADING1)
    private fun onHeading2Clicked() = applyLineStyle(LineStyleType.HEADING2)
    private fun onHeading3Clicked() = applyLineStyle(LineStyleType.HEADING3)

    private fun onOrderedListClicked() = applyLineStyle(LineStyleType.ORDERED_LIST)
    private fun onUnorderedListClicked() = applyLineStyle(LineStyleType.UNORDERED_LIST)

    private fun onCodeBlockClicked() = applyLineStyle(LineStyleType.CODE_BLOCK)

    // 清除当前行所有样式
    private fun onClearStyleClicked() {
        clearCurrentLineStyle()
    }

    private fun clearCurrentLineStyle() {
        val sel = editor.selectionStart
        val text = editor.text
        val lineStart = text.lastIndexOf('\n', sel - 1).let { if (it == -1) 0 else it + 1 }
        val lineEnd = text.indexOf('\n', sel).let { if (it == -1) text.length else it }

        // 1. 清除 Spannable 样式
        val spanTypes = arrayOf(
            StyleSpan::class.java,
            ForegroundColorSpan::class.java,
            UnderlineSpan::class.java,
            StrikethroughSpan::class.java,
            BulletSpan::class.java,
            BackgroundColorSpan::class.java,
            TypefaceSpan::class.java
        )
        for (type in spanTypes) {
            val spans = text.getSpans(lineStart, lineEnd, type)
            for (span in spans) {
                text.removeSpan(span)
            }
        }

        // 2. 清除列表前缀（• 或 1. ）
        var lineText = text.subSequence(lineStart, lineEnd).toString()
        val numberRegex = Regex("^\\d+\\.\\s")
        val bulletPrefix = "• "

        lineText = when {
            lineText.trimStart().startsWith(bulletPrefix) ->
                lineText.replaceFirst(bulletPrefix, "")

            numberRegex.containsMatchIn(lineText.trimStart()) ->
                lineText.replaceFirst(numberRegex, "")

            else -> lineText
        }

        // 3. 清除缩进（tab 或 4 个空格）
        lineText = when {
            lineText.startsWith("\t") -> lineText.removePrefix("\t")
            lineText.startsWith("    ") -> lineText.removePrefix("    ")
            else -> lineText
        }

        // 替换原有行内容
        text.replace(lineStart, lineEnd, lineText)

        // 4. 恢复字体颜色为黑色（仅对整个 EditText）
        editor.setTextColor(Color.BLACK)

        // 5. 恢复字体大小为默认大小（例如 16sp）
        editor.setTextSize(TypedValue.COMPLEX_UNIT_SP, 16f)
    }


    // ---------- 具体样式函数实现

    private fun applyOrderedList(lineStart: Int, lineEnd: Int) {
        val text = editor.text

        // 先去除所有已有样式（包括列表标记）避免叠加
        clearLineStyles(lineStart, lineEnd)

        // 加数字列表标记
        // 这里简单实现：插入 "1. "，实际可根据前面数字递增更完善
        val lineText = text.subSequence(lineStart, lineEnd).toString()
        val newText = if (lineText.trimStart().matches(Regex("^\\d+\\.\\s"))) {
            // 如果已经是数字列表，去掉数字列表标记（实现切换）
            lineText.replace(Regex("^\\d+\\.\\s"), "")
        } else {
            "1. $lineText"
        }
        text.replace(lineStart, lineEnd, newText)
    }

    private fun applyUnorderedList(lineStart: Int, lineEnd: Int) {
        val text = editor.text

        clearLineStyles(lineStart, lineEnd)

        val lineText = text.subSequence(lineStart, lineEnd).toString()
        val newText = if (lineText.trimStart().startsWith("• ")) {
            // 去除无序列表标记
            lineText.replaceFirst("• ", "")
        } else {
            "• $lineText"
        }
        text.replace(lineStart, lineEnd, newText)
    }

    private fun applyCodeBlock(lineStart: Int, lineEnd: Int) {
        val text = editor.text

        // 先清除
        clearLineStyles(lineStart, lineEnd)

        // 背景灰色、等宽字体、绿色字体
        text.setSpan(
            BackgroundColorSpan(Color.parseColor("#f0f0f0")),
            lineStart,
            lineEnd,
            Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
        )
        text.setSpan(
            TypefaceSpan("monospace"),
            lineStart,
            lineEnd,
            Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
        )
        text.setSpan(
            ForegroundColorSpan(Color.parseColor("#008000")),
            lineStart,
            lineEnd,
            Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
        )
    }

    private fun onFormatIndentIncreaseClicked() {
        val sel = editor.selectionStart
        if (sel < 0) return
        val text = editor.text
        val lineStart = text.lastIndexOf('\n', sel - 1).let { if (it == -1) 0 else it + 1 }
        text.insert(lineStart, "\t")
    }

    private fun onFormatIndentDecreaseClicked() {
        val sel = editor.selectionStart
        if (sel < 0) return
        val text = editor.text
        val lineStart = text.lastIndexOf('\n', sel - 1).let { if (it == -1) 0 else it + 1 }
        val lineEnd = text.indexOf('\n', sel).let { if (it == -1) text.length else it }
        val lineText = text.subSequence(lineStart, lineEnd).toString()
        when {
            lineText.startsWith("\t") -> text.delete(lineStart, lineStart + 1)
            lineText.startsWith("    ") -> text.delete(lineStart, lineStart + 4)
        }
    }

    private fun onImageClicked() {
        imagePickerLauncher?.launch("image/*")
    }

    fun insertImage(uri: Uri) {
        try {
            val inputStream = context.contentResolver.openInputStream(uri)
            val bitmap = BitmapFactory.decodeStream(inputStream)
            inputStream?.close()

            val maxHeightPx = 300.dpToPx()
            val maxWidthPx = editor.width * 2 / 3

            val scale = if (bitmap.height > maxHeightPx) {
                maxHeightPx.toFloat() / bitmap.height
            } else {
                1f
            }

            val targetWidth = (bitmap.width * scale).toInt().coerceAtMost(maxWidthPx)
            val targetHeight = (bitmap.height * scale).toInt()

            val drawable = BitmapDrawable(resources, bitmap)
            drawable.setBounds(0, 0, targetWidth, targetHeight)

            val imageSpan = ImageSpan(drawable, uri.toString())
            val spannable = SpannableString("\n￼\n") // 使用 ￼ 占位符代表图片

            spannable.setSpan(imageSpan, 1, 2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)

            val sel = editor.selectionStart
            editor.text.insert(sel, spannable)

            // 自动将光标移动到图片后面的新行
            val newCursorPos = sel + spannable.length
            editor.setSelection(minOf(newCursorPos, editor.text.length))
        } catch (e: Exception) {
            e.printStackTrace()
            Toast.makeText(context, "插入图片失败", Toast.LENGTH_SHORT).show()
        }
    }


    // ---- 工具函数

    private fun Int.dpToPx(): Int = (this * resources.displayMetrics.density).toInt()

    // 获取当前行的样式类型（用于判断是否允许切换样式，非强制）
    private fun getCurrentLineStyle(): LineStyleType {
        val sel = editor.selectionStart
        if (sel < 0) return LineStyleType.NONE
        val text = editor.text
        val lineStart = text.lastIndexOf('\n', sel - 1).let { if (it == -1) 0 else it + 1 }
        val lineEnd = text.indexOf('\n', sel).let { if (it == -1) text.length else it }

        val spans = text.getSpans(lineStart, lineEnd, Any::class.java)

        return when {
            spans.any {
                it is BulletSpan || text.subSequence(lineStart, lineEnd).startsWith("• ")
            } -> LineStyleType.UNORDERED_LIST
//            spans.any { it is ForegroundColorSpan && text.subSequence(lineStart, lineEnd).startsWith(Regex("^\\d+\\.\\s")) } -> LineStyleType.ORDERED_LIST
            spans.any { it is BackgroundColorSpan } -> LineStyleType.CODE_BLOCK
            spans.any { it is StyleSpan && (it.style == Typeface.BOLD) } -> LineStyleType.BOLD
            spans.any { it is StyleSpan && (it.style == Typeface.ITALIC) } -> LineStyleType.ITALIC
            spans.any { it is UnderlineSpan } -> LineStyleType.UNDERLINE
            spans.any { it is StrikethroughSpan } -> LineStyleType.STRIKETHROUGH
            else -> LineStyleType.NONE
        }
    }

    fun setImagePickerLauncher(launcher: ActivityResultLauncher<String>) {
        this.imagePickerLauncher = launcher
    }

    private fun Pair<*, IntRange>.firstOffset(): Int = when (first) {
        is StyleSpan -> 2
        is StrikethroughSpan -> 2
        is UnderlineSpan -> 3
        else -> 0
    }

    override fun exportMarkdown(): String {
        val sb = StringBuilder()
        val text = editor.text
        var i = 0
        while (i < text.length) {
            val lineEnd = text.indexOf('\n', i).let { if (it == -1) text.length else it + 1 }
            val line = text.subSequence(i, lineEnd)

            // 获取该行的样式 span
            val spans = text.getSpans(i, lineEnd, Any::class.java)

            val hasBold = spans.any { it is StyleSpan && it.style == Typeface.BOLD }
            val hasItalic = spans.any { it is StyleSpan && it.style == Typeface.ITALIC }
            val hasUnderline = spans.any { it is UnderlineSpan }
            val hasStrikethrough = spans.any { it is StrikethroughSpan }
            val hasCode = line.startsWith("```") && line.endsWith("```")

            val imageSpans = text.getSpans(i, lineEnd, ImageSpan::class.java)
            if (imageSpans.isNotEmpty()) {
                val uri = imageSpans[0].source ?: ""
                sb.append("![]($uri)\n")
                i = lineEnd
                continue
            }

            var lineText = line.toString().trimEnd('\n')

            if (hasCode) {
                lineText = lineText.removePrefix("```").removeSuffix("```")
                sb.append("```\n$lineText\n```\n")
            } else {
                if (lineText.matches(Regex("^\\d+\\.\\s.*"))) {
                    sb.append(lineText).append("\n")
                } else if (lineText.startsWith("• ")) {
                    sb.append("- ").append(lineText.removePrefix("• ")).append("\n")
                } else {
                    if (hasBold) lineText = "**$lineText**"
                    if (hasItalic) lineText = "_${lineText}_"
                    if (hasStrikethrough) lineText = "~~$lineText~~"
                    if (hasUnderline) lineText = "<u>$lineText</u>"

                    sb.append(lineText).append("\n")
                }
            }

            i = lineEnd
        }
        return sb.toString()
    }

    override fun importMarkdown(markdown: String) {
        val lines = markdown.lines()
        editor.setText("") // 清空旧内容

        lines.forEachIndexed { index, rawLine ->
            val line = rawLine.trim()
            val spannable = SpannableStringBuilder()

            when {
                line.startsWith("```") -> {
                    // 多行代码块
                    val codeBlock = StringBuilder()
                    var i = index + 1
                    while (i < lines.size && lines[i] != "```") {
                        codeBlock.append(lines[i]).append("\n")
                        i++
                    }
                    spannable.append(codeBlock.toString())
                    spannable.setSpan(
                        BackgroundColorSpan(Color.LTGRAY),
                        0, spannable.length,
                        Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
                    )
                    editor.append(spannable)
                    editor.append("\n")
                    return@forEachIndexed
                }

                line.matches(Regex("^\\d+\\.\\s.*")) -> {
                    spannable.append(line)
                }

                line.startsWith("- ") -> {
                    spannable.append("• ").append(line.removePrefix("- "))
                }

                line.startsWith("![](") && line.endsWith(")") -> {
                    val uri = line.substringAfter("![](").removeSuffix(")")
                    insertImage(Uri.parse(uri))
                    return@forEachIndexed
                }

                else -> {
                    var content = line

                    val spans = mutableListOf<Pair<Any, IntRange>>()

                    Regex("""\*\*(.*?)\*\*""").findAll(content).forEach {
                        spans.add(StyleSpan(Typeface.BOLD) to it.range)
                    }
                    Regex("""_(.*?)_""").findAll(content).forEach {
                        spans.add(StyleSpan(Typeface.ITALIC) to it.range)
                    }
                    Regex("""~~(.*?)~~""").findAll(content).forEach {
                        spans.add(StrikethroughSpan() to it.range)
                    }
                    Regex("""<u>(.*?)</u>""").findAll(content).forEach {
                        spans.add(UnderlineSpan() to it.range)
                    }

                    // 替换掉 markdown 控制符
                    content = content.replace("**", "")
                        .replace("_", "")
                        .replace("~~", "")
                        .replace("<u>", "")
                        .replace("</u>", "")

                    spannable.append(content)

                    // 应用样式
                    spans.forEach {
                        val start = it.second.first - it.firstOffset()
                        val end = it.second.last + 1 - it.firstOffset()
                        spannable.setSpan(it.first, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
                    }

                    editor.append(spannable)
                }
            }
            editor.append("\n")
        }

    }

    fun isEmpty(): Boolean {
        return editor.text.toString().trim().isEmpty()
    }

    fun reset() {
        // 清空内容
        editor.text.clear()

        // 恢复默认文字颜色
        currentTextColor = Color.BLACK
        editor.setTextColor(currentTextColor)

        // 恢复默认字体大小（你默认用的是 16sp）
        editor.setTextSize(TypedValue.COMPLEX_UNIT_SP, 16f)

        // 清除焦点，防止立刻又触发输入监听
        editor.clearFocus()
    }
}
